package com.menghao.sso.client.filter;

import com.menghao.sso.client.util.CommonUtils;
import lombok.Setter;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.StringUtils;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

/**
 * <p>客户端过滤器抽象类.<br>
 *
 * @author menghao.
 * @version 2017/11/15.
 */
public abstract class AbstractCasFilter implements Filter {

    protected final Log log = LogFactory.getLog(this.getClass());

    /*
        请求服务主机名
     */
    @Setter
    private String clientHost;
    /*
        cas服务端地址
     */
    @Setter
    protected String serverHost;

    private static final String HTTP = "http://";

    protected String makeLoginRequest(String originalRequest) throws UnsupportedEncodingException {
        return HTTP + serverHost + CommonUtils.LOGIN_URL + "?" + CommonUtils.SERVICE + "=" + URLEncoder.encode(originalRequest, "UTF-8");
    }

    protected String makeValidateSTRequest(String originalRequest) throws UnsupportedEncodingException {
        return HTTP + serverHost + CommonUtils.VALIDATE_URL + "?" + CommonUtils.SERVICE + "=" + URLEncoder.encode(originalRequest, "UTF-8") + "&" + CommonUtils.ST_ID + "={serviceTicket}";
    }

    protected String makeValidateTGTRequest(String originalRequest, String grantingTicket) throws UnsupportedEncodingException {
        return HTTP + serverHost + CommonUtils.VALIDATE_URL + "?" + CommonUtils.SERVICE + "=" + URLEncoder.encode(originalRequest, "UTF-8") + "&" + CommonUtils.TGT_ID + "=" + grantingTicket;
    }

    protected String makeLogoutRequest() {
        return HTTP + serverHost + CommonUtils.LOGOUT_URL + "?username={username}&ticket={ticket}";
    }

    protected String makeOriginalRequest(HttpServletRequest request, HttpServletResponse response) {
        StringBuilder builder = new StringBuilder();
        builder.append(request.isSecure() ? "https://" : "http://");
        builder.append(clientHost);
        builder.append(request.getRequestURI());
        // 如果存在查询参数，将参数抽取拼接
        if (StringUtils.hasLength(request.getQueryString())) {
            int index = request.getQueryString().indexOf(CommonUtils.ST_ID + "=");
            // 默认规则ticket放在查询参数最后
            if (index == -1) {
                builder.append("?").append(request.getQueryString());
            } else if (index == 0) {
                // do nothing
            } else {
                index = request.getQueryString().indexOf("&" + CommonUtils.ST_ID + "=");
                if (index == -1) {
                    builder.append("?").append(request.getQueryString());
                } else {
                    builder.append("?").append(request.getQueryString().substring(0, index));
                }
            }
        }
        final String returnValue = response.encodeURL(builder.toString());
        if (log.isDebugEnabled()) {
            log.debug("serviceUrl make: " + returnValue);
        }
        return returnValue;
    }

    protected abstract void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws IOException, ServletException;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    /*
        此步对request和response做了统一转型
     */
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        doFilterInternal((HttpServletRequest) request, (HttpServletResponse) response, chain);
    }

    @Override
    public void destroy() {

    }

}
